package bsh.asm.acessor;

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import bsh.CompilationState;
import bsh.exception.CompilationAssertionFailed;
import bsh.meta.FieldDescriptor;
import bsh.meta.TypeWrapper;

/**
 * @author takeshi
 */
public class FieldObjectAcessor implements ObjectAccessor {

    private final FieldDescriptor field;

    /**
     * @param field {@link FieldDescriptor}
     */
    public FieldObjectAcessor(FieldDescriptor field) {
        super();
        this.field = field;
    }

    /**
     * {@inheritDoc}
     */
    public void loadObject(MethodVisitor visitor, CompilationState state) {
        this.field.writeGetValueCode(visitor, state);
    }

    /**
     * {@inheritDoc}
     */
    public TypeWrapper type() {
        return this.field.fieldType();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "." + this.field.fieldName();
    }

    /**
     * {@inheritDoc}
     */
    public void preStore(MethodVisitor visitor, CompilationState state) {
        if (this.readOnly()) {
            throw new CompilationAssertionFailed(this + " is readonly");
        }
    }

    /**
     * {@inheritDoc}
     */
    public boolean readOnly() {
        return (this.field.asmModifiers() & Opcodes.ACC_FINAL) != 0;
    }

    /**
     * {@inheritDoc}
     */
    public void storeObject(MethodVisitor visitor, CompilationState state) {
        this.field.writeWriteValueCode(visitor, state);
    }

    /**
     * @return the field
     */
    public FieldDescriptor getField() {
        return field;
    }

}
